package com.greejoy.score.service;

import android.app.Service;
import android.content.Intent;
import android.os.IBinder;
import android.util.Log;

import androidx.annotation.Nullable;

import com.alibaba.fastjson.JSON;
import com.greejoy.score.MyApplication;
import com.greejoy.score.R;
import com.greejoy.score.activity.ScoreActivity;
import com.greejoy.score.domain.WsMessage;
import com.greejoy.score.utils.WsUtils;

import okhttp3.WebSocket;
import okhttp3.WebSocketListener;
import retrofit2.Retrofit;

public class WebsocketService extends Service {

    private MyApplication app;
    private Retrofit retrofit;
    private HttpService httpService;

    private WebSocket myWebSocket;
    private String wsUrl;
    private boolean wsIsConnected = false;
    private boolean wsIsConnecting = false;

    @Nullable
    @Override
    public IBinder onBind(Intent intent) {
        return null;
    }

    @Override
    public void onCreate() {
        super.onCreate();
        app = MyApplication.getInstance();
    }


    @Override
    public int onStartCommand(Intent intent, int flags, int startId) {

        Intent broadcastIntent = new Intent();
        broadcastIntent.setAction(getString(R.string.broadcast_action));
        broadcastIntent.putExtra("msg", "showWsLoading");
        sendBroadcast(broadcastIntent);

        String httpUrl = app.dataMap.get("httpUrl");
        wsUrl = app.dataMap.get("wsUrl");
        retrofit = new Retrofit.Builder().baseUrl(httpUrl).build();
        httpService = retrofit.create(HttpService.class);
        wsIsConnecting = true;
        if(myWebSocket != null){
            myWebSocket.close(4444, "Connection closed");
        }
        myWebSocket = WsUtils.connect(wsUrl, new MyWebSocketListener());

        return super.onStartCommand(intent, flags, startId);
    }

    @Override
    public void onDestroy() {
        super.onDestroy();
        myWebSocket.close(4444, "Manually close the connection");
    }


    class MyWebSocketListener extends WebSocketListener {
        @Override
        public void onOpen(WebSocket webSocket, okhttp3.Response response) {
            super.onOpen(webSocket, response);
            wsIsConnected = true;

            Intent intent = new Intent();
            intent.setAction(getString(R.string.broadcast_action));
            intent.putExtra("msg", "hideWsLoading");
            sendBroadcast(intent);
        }

        @Override
        public void onMessage(WebSocket webSocket, String text) {
            super.onMessage(webSocket, text);
            WsMessage message = JSON.parseObject(text, WsMessage.class);

            Intent broadcastIntent = new Intent();
            broadcastIntent.setAction(getString(R.string.broadcast_action));

            switch (message.getType()) {
                case "judgeScore":
                    if(app.dataMap.get("judgeId") == null){
                        break;
                    }
                    Long judgeId = Long.valueOf(app.dataMap.get("judgeId"));
                    String judgeName = app.dataMap.get("judgeName");
                    if (message.getJudgeIds().contains(judgeId)) {
                        Intent intent = new Intent(WebsocketService.this, ScoreActivity.class);
                        intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK|Intent.FLAG_ACTIVITY_CLEAR_TASK);
                        intent.putExtra("judge_id", judgeId);
                        intent.putExtra("judge_name", judgeName);
                        startActivity(intent);
                    }
                    break;
                case "playMusic":
                    broadcastIntent.putExtra("msg", "playMusic");
                    broadcastIntent.putExtra("placeId", message.getPlaceId());
                    broadcastIntent.putExtra("registerId", message.getRegisterId());
                    broadcastIntent.putExtra("filename", message.getFilename());
                    sendBroadcast(broadcastIntent);
                    break;
                case "pauseMusic":
                    broadcastIntent.putExtra("msg", "pauseMusic");
                    broadcastIntent.putExtra("placeId", message.getPlaceId());
                    sendBroadcast(broadcastIntent);
                    break;
                case "replayMusic":
                    broadcastIntent.putExtra("msg", "replayMusic");
                    broadcastIntent.putExtra("placeId", message.getPlaceId());
                    sendBroadcast(broadcastIntent);
                    break;
                case "setLoop":
                    broadcastIntent.putExtra("msg", "setLoop");
                    broadcastIntent.putExtra("placeId", message.getPlaceId());
                    broadcastIntent.putExtra("loop", message.getLoop());
                    sendBroadcast(broadcastIntent);
                    break;
                case "setVolume":
                    broadcastIntent.putExtra("msg", "setVolume");
                    broadcastIntent.putExtra("placeId", message.getPlaceId());
                    broadcastIntent.putExtra("volume", message.getVolume());
                    sendBroadcast(broadcastIntent);
                    break;
            }
        }

        @Override
        public void onClosing(WebSocket webSocket, int code, String reason) {
            super.onClosing(webSocket, code, reason);
            // 退出活动关闭不用重连
            if (code == 4444) {
                return;
            }

            Intent intent = new Intent();
            intent.setAction(getString(R.string.broadcast_action));
            intent.putExtra("msg", "showWsLoading");
            sendBroadcast(intent);

            wsIsConnected = false;
            wsIsConnecting = true;
            myWebSocket = WsUtils.connect(wsUrl, this);

        }

        @Override
        public void onFailure(WebSocket webSocket, Throwable t, okhttp3.Response response) {
            super.onFailure(webSocket, t, response);

            Log.d("zhuwei", "onFailure:" + t.getMessage());

            if(t.getMessage() != null && t.getMessage().contains("connect")){
                webSocket.close(4444, "Connection failure");

                Intent intent = new Intent();
                intent.setAction(getString(R.string.broadcast_action));
                intent.putExtra("msg", "showWsLoading");
                sendBroadcast(intent);

                wsIsConnected = false;
                wsIsConnecting = false;
                while (!wsIsConnected && !wsIsConnecting) {
                    try {
                        Thread.sleep(3000);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                    wsIsConnecting = true;
                    myWebSocket = WsUtils.connect(wsUrl, this);
                }

            }
        }
    }

}